Skip to content

Optionally produce coeffs_reconstruct stream for MPAS-O, link coeffs file from database for Omega#448

Open
cbegeman wants to merge 6 commits intoE3SM-Project:mainfrom
cbegeman:ocn/add-optional-coeffs-reconstruct-output
Open

Optionally produce coeffs_reconstruct stream for MPAS-O, link coeffs file from database for Omega#448
cbegeman wants to merge 6 commits intoE3SM-Project:mainfrom
cbegeman:ocn/add-optional-coeffs-reconstruct-output

Conversation

@cbegeman
Copy link
Copy Markdown
Collaborator

@cbegeman cbegeman commented Jan 12, 2026

The following changes are needed because only MPAS-O produces the coefficients needed to reconstruct zonal and meridional components from edge fields:

  • Use config option to determine whether to add coeffs_reconstruct to the stream for forward steps with MPAS-O (ensure this capability can only be turned on with MPAS-O)
  • Add the netcdf files containing the coeffs_reconstruct stream to the input database (see Optionally produce coeffs_reconstruct stream for MPAS-O, link coeffs file from database for Omega #448 (comment))
  • Link the netcdf files containing the coeffs_reconstruct stream within the forward step when the model is Omega
  • Analysis or viz involving *Zonal, *Meridional fields should use the output stream if present or reconstruct the fields using coeffs

Checklist

  • User's Guide has been updated
  • Developer's Guide has been updated
  • API documentation in the Developer's Guide (api.md) has any new or modified class, method and/or functions listed
  • Documentation has been built locally and changes look as expected
  • Testing comment in the PR documents testing used to verify the changes
  • New tests have been added to a test suite

@cbegeman
Copy link
Copy Markdown
Collaborator Author

cbegeman commented Jan 12, 2026

@xylar Let me know what you think.

Pro of using this approach: no need to run a separate forward step besides those being run. (coeffs_reconstruct doesn't have a time dimension so I think this stream is only written once but it's worth double checking.) I was also thinking we could set write_coeffs_reconstruct = True in polaris/ocean/mpas_ocean.cfg and run whichever cases we want to have cached.

Con of using this approach: if there are multiple forward steps for a single test case (corresponding to the config file for which write_coeffs_reconstruct = True, all will produce the coeffs_reconstruct stream.

@cbegeman cbegeman force-pushed the ocn/add-optional-coeffs-reconstruct-output branch from 3da3ae4 to b548c38 Compare January 12, 2026 22:21
@cbegeman
Copy link
Copy Markdown
Collaborator Author

The plan will be to

  1. Cache all mesh steps for test cases that support Omega (https://docs.e3sm.org/polaris/main/developers_guide/api.html#cache)
  2. Use cached mesh steps in Omega PR and nightly suites
  3. Add coeffs_reconstruct.nc files corresponding to each mesh to the input_database with date stamps
  4. For any viz steps that support Omega and use reconstructed velocity fields, load coeffs_reconstruct.nc and use reconstruct_variable https://github.com/MPAS-Dev/MPAS-Tools/blob/297a1b0bf08c0d9e191c0b0e1d35ae315ee49617/conda_package/mpas_tools/vector/reconstruct.py#L2-L18

@cbegeman
Copy link
Copy Markdown
Collaborator Author

This PR addresses #445

@cbegeman cbegeman force-pushed the ocn/add-optional-coeffs-reconstruct-output branch from b548c38 to 36bad9c Compare January 27, 2026 00:56
@cbegeman
Copy link
Copy Markdown
Collaborator Author

cbegeman commented Apr 3, 2026

Input database additions

When tests have multiple resolutions, the coefficient files are saved as {res}_coeffs.nc otherwise they are named coeffs.nc

  • Spherical mesh files are stored at {database_root}/mesh/{prefix} where prefix is either qu or icos. A helper function parse_mesh_path has been added to polaris.mesh.base
  • Planar mesh files are stored at {database_root}/ocean/{task_name}

@cbegeman cbegeman self-assigned this Apr 3, 2026
@cbegeman cbegeman added ocean Related to the ocean component mesh Related to the mesh component labels Apr 3, 2026
@cbegeman cbegeman changed the title Use config option to determine whether to add coeffs_reconstruct to the stream Optionally produce coeffs_reconstruct stream for MPAS-O, link coeffs file from database for Omega Apr 3, 2026
@cbegeman cbegeman force-pushed the ocn/add-optional-coeffs-reconstruct-output branch from 36bad9c to 2e84e77 Compare April 3, 2026 21:43
@cbegeman cbegeman marked this pull request as ready for review April 4, 2026 15:29
@cbegeman cbegeman requested a review from xylar April 4, 2026 15:29
@cbegeman
Copy link
Copy Markdown
Collaborator Author

cbegeman commented Apr 4, 2026

icos/rotation_2d 480km results produced by polaris/mpas_tools with coeffs for Omega:

image image

results produced internally by MPAS-O:

image image

@cbegeman
Copy link
Copy Markdown
Collaborator Author

cbegeman commented Apr 7, 2026

@xylar Ready for review when you have a chance

@xylar
Copy link
Copy Markdown
Collaborator

xylar commented Apr 7, 2026

Great, I'll make this a priority.

Copy link
Copy Markdown
Collaborator

@xylar xylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good!

Just two suggestions for keeping the code clean.

Other than that, I think it just needs a little bit of documentation. I'll go ahead and approve on the assumption that goes in.

It doesn't look like more testing is needed on my part but let me know if you'd like some.

self.write_coeffs_reconstruct = False
if self.write_coeffs_reconstruct:
model = self.config.get('ocean', 'model')
if not model == 'mpas-ocean':
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For whatever reason, I've been lead to believe this is preferred:

Suggested change
if not model == 'mpas-ocean':
if model != 'mpas-ocean':

Comment on lines +273 to +311
if reconstruct_variables is None:
reconstruct_variables = []
for variable in reconstruct_variables:
if variable in ds.keys():
if 'normal' in variable:
out_var_name = variable.replace('normal', '').lower()
else:
out_var_name = variable
if (
f'{out_var_name}Zonal' in ds.keys()
and f'{out_var_name}Meridional' in ds.keys()
):
return ds
if mesh_filename is None:
raise ValueError(
'mesh_filename must be provided to '
f'open_model_dataset for reconstruction of {variable}'
)
ds_mesh = xr.open_dataset(mesh_filename)
if coeffs_filename is None:
raise ValueError(
'coeffs_filename must be provided to '
f'open_model_dataset for reconstruction of {variable}'
)
ds_coeff = xr.open_dataset(coeffs_filename)
coeffs_reconstruct = ds_coeff.coeffs_reconstruct
reconstruct_variable(
out_var_name,
ds[variable],
ds_mesh,
coeffs_reconstruct,
ds,
quiet=True,
)
else:
raise ValueError(
f'User requested vector reconstruction for {variable} but '
f"it isn't present in the dataset."
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we move this to a helper function, just to keep things tidy?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I'll make these changes and flesh out the docs. Thanks for reviewing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mesh Related to the mesh component ocean Related to the ocean component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants